package org.example.fileservice.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.example.fileservice.pojo.FileInfo;
import org.example.fileservice.mapper.FileInfoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

@Service
public class FileService extends ServiceImpl<FileInfoMapper, FileInfo> {

    @Autowired
    private MinioClient minioClient;

    @Value("${minio.bucketName}")
    private String bucketName;

    public FileInfo uploadFile(MultipartFile file) throws Exception {
        // 生成唯一文件名
        String originalName = file.getOriginalFilename();
        String fileType = getFileType(originalName);
        String fileName = UUID.randomUUID().toString() + "." + fileType;
        String minioPath = "documents/" + fileName;

        // 上传到MinIO
        minioClient.putObject(
                PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(minioPath)
                        .stream(file.getInputStream(), file.getSize(), -1)
                        .contentType(file.getContentType())
                        .build()
        );

        // 解析文件内容
        String content = parseFileContent(file, fileType);

        // 保存文件信息到数据库
        FileInfo fileInfo = new FileInfo();
        fileInfo.setFileName(fileName);
        fileInfo.setOriginalName(originalName);
        fileInfo.setFileType(fileType);
        fileInfo.setFileSize(file.getSize());
        fileInfo.setMinioPath(minioPath);
        fileInfo.setFileContent(content);
        fileInfo.setUploadTime(LocalDateTime.now());
        fileInfo.setStatus(1); // 解析完成
        fileInfo.setCreatedAt(LocalDateTime.now());
        fileInfo.setUpdatedAt(LocalDateTime.now());

        save(fileInfo);
        return fileInfo;
    }

    private String getFileType(String fileName) {
        if (fileName == null) return "unknown";
        int lastDot = fileName.lastIndexOf('.');
        return lastDot > 0 ? fileName.substring(lastDot + 1).toLowerCase() : "unknown";
    }

    private String parseFileContent(MultipartFile file, String fileType) throws IOException {
        InputStream inputStream = file.getInputStream();
        
        switch (fileType) {
            case "pdf":
                return parsePdf(inputStream);
            case "docx":
            case "doc":
                return parseWord(inputStream);
            case "txt":
                return parseTxt(inputStream);
            default:
                return "不支持的文件类型";
        }
    }

    private String parsePdf(InputStream inputStream) throws IOException {
        try (PDDocument document = PDDocument.load(inputStream)) {
            PDFTextStripper stripper = new PDFTextStripper();
            return stripper.getText(document);
        }
    }

    private String parseWord(InputStream inputStream) throws IOException {
        try (XWPFDocument document = new XWPFDocument(inputStream);
             XWPFWordExtractor extractor = new XWPFWordExtractor(document)) {
            return extractor.getText();
        }
    }

    private String parseTxt(InputStream inputStream) throws IOException {
        StringBuilder content = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                content.append(line).append("\n");
            }
        }
        return content.toString();
    }

    public void clearAllFiles() throws Exception {
        // 查询所有文件
        List<FileInfo> files = list();
        // 删除MinIO对象
        for (FileInfo file : files) {
            if (file.getMinioPath() != null) {
                minioClient.removeObject(
                    io.minio.RemoveObjectArgs.builder()
                        .bucket(bucketName)
                        .object(file.getMinioPath())
                        .build()
                );
            }
        }
        // 删除数据库记录
        remove(null);
    }
}